home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-09-27 | 4.5 KB | 151 lines | [TEXT/YHS2] |
- {-*********************************************************************
- MODULE R_UTILITY
-
- This module contains all the basic utility functions that the other
- modules need to have to write their code. These are made generally
- low level functions, manipulating vectors or defining very
- general functions
-
- **********************************************************************-}
-
-
- module R_Utility (vtovf,vftov,
- vplus, vmin, mid, partway,
- mag,
- reduce, power, i,
- member, repeat, zip1, zip2, zip3, rept, replicate,
- mapc,
- append, flatten, rptseq, osc
- ) where
-
- import R_Ptypes
-
-
- -- CONVERSION
-
- -- vtovf takes a vector of integers, and converts it to a vector of floats
- vtovf :: Vec -> Vecfloat
- vtovf (x,y) = (fromIntegral x,fromIntegral y)
-
- -- vftov takes a vector of floats and converts it to a vector of integers.
- -- It rounds the floats off to do this.
- vftov :: Vecfloat -> Vec
- vftov (x,y) = (round x,round y)
-
-
- -- VECTOR OPERATIONS:
-
- -- vector addition
- vplus:: Vec -> Vec -> Vec
- vplus (a,b) (c,d) = (a+c,b+d)
-
- -- vector substraction
- vmin:: Vec -> Vec -> Vec
- vmin (a,b) (c,d) = (a-c,b-d)
-
- -- finds the midpoint between two vectors
- mid:: Vec -> Vec -> Vec
- mid (x1,y1) (x2,y2) = (div (x1+x2) 2,div (y1+y2) 2 )
-
- -- finds a point p/q along the way between two vectors
- partway :: Int -> Int -> [Vec] -> Vec
- partway p q [(x1,y1),(x2,y2)]
- = vplus (x1,y1) ( div (p*(x2-x1)) q, div (p*(y2-y1)) q )
-
- -- finds the magnitude of two vectors
- mag :: Vec -> Int
- mag p = round (magfloat (vtovf p))
-
- magfloat :: Vecfloat -> Float
- magfloat (x,y) = sqrt (x*x + y*y)
-
- -- returns a vector at right angles to the input vector
- normal:: Vec -> Vec
- normal (x,y) = (-y,x)
-
- -- returns the first vector projected onto the second
- project:: Vec -> Vec -> Vec
- project (vx,vy) (wx,wy) = partway (vx*wx+vy*wy) (mw*mw) [(0,0),(wx,wy)]
- where mw = mag (wx,wy)
-
-
- -- HIGHER-ORDER FUNCTIONS:
-
- -- just foldr1. It applies a function of two inputs to an entire list
- -- recursively, and displays the single element result
- reduce :: (a->a->a) -> [a] -> a
- reduce = foldr1
-
- -- power applies a single function n times to a seed
- power :: Int -> (a->a) -> a -> a
- power 0 f seed = seed
- power (n+1) f seed = f (power n f seed)
-
- -- i takes an element and returns an infinite list of them
- i :: a -> [a]
- i x = x: (i x)
-
- -- checks to see if x is in the list of xs
- member :: (Eq a) => [a] -> a -> Bool
- member [] x = False
- member (y:ys) x = x == y || member ys x
-
- -- zip1 takes lists of lists, and rearranges them so that all the first
- -- elements are in the first list, all the second in the second and so on.
- zip1 :: (Eq a) => [[a]] -> [[a]]
- zip1 xs | member xs [] = []
- zip1 xs = (map head xs):(zip1 (map tail xs))
-
- -- takes two lists and makes a list of tuples.
- zip2 :: [a] -> [b] -> [(a,b)]
- zip2=zip
-
- -- rept takes a function and a list of elements, and applies the function
- -- n-1 times to the n-th element
- rept :: (a->a) -> a -> [a]
- rept f x = x:(rept f (f x))
-
- -- replicate creates an list n elements long of a, with the function
- -- applies to the n-th element n-1 times.
- replicate :: Int -> (a->a->a) -> a -> a -> a
- replicate 0 f zero a = zero
- replicate 1 f zero a = a
- replicate (n+2) f zero a = f a (replicate (n+1) f zero a)
-
- -- mapc is a map function for lists of functions (behaviours)
- mapc :: (a->b) -> [c->a] -> [c->b]
- mapc f as = [f.a | a <- as]
-
-
- -- FUNCTIONS OVER SEQUENCES:
-
- -- append takes a list of lists, and makes them into one giant happy list.
- append :: [[a]] -> [a]
- append = foldr (++) []
-
- -- flatten takes a list of lists of tuples and gives one giant happy list
- -- of single elements back.
- flatten:: [[(a,a)]] -> [a]
- flatten s = foldr f [] (append s)
- where f (x,y) [] = [x,y]
- f (x,y) (z:zs) = x:y:(z:zs)
-
- -- rptseq takes a list of elements and applies a function to them,
- -- n-1 times for the n-th element, but using map
- rptseq :: (a->a) -> [a] -> [a]
- rptseq f [] = []
- rptseq f (x:xs) = x:rptseq f (map f xs)
-
- -- osc takes a list, and makes sure it oscillates. If the head is
- -- equal to the tail, it simply repeats the sequence infinitely. If
- -- the head is not equal to the tail, it adds the sequence then adds
- -- the reversed sequence minus the first and last elements, and then repeats
- osc :: [a] -> [a]
- osc s | (length s) == 0 = []
- osc s | (length s) == 1 = head s: osc s
- osc s = (s ++ (((tail.reverse).tail) s)) ++ (osc s)
-
-
-
-
-